package com.suzhe.ymall.common.handler.impl;

import com.suzhe.ymall.common.annotation.LoginAuth;
import com.suzhe.ymall.common.enums.ApiCode;
import com.suzhe.ymall.common.exception.AuthorizationException;
import com.suzhe.ymall.common.handler.AuthorizationHander;
import com.suzhe.ymall.common.pojo.SysLoginUser;
import com.suzhe.ymall.common.service.IPermissionService;
import com.suzhe.ymall.common.utils.RedisKeys;
import com.suzhe.ymall.common.utils.RedisTemplateUtils;
import com.suzhe.ymall.common.utils.LoginUserUtils;
import com.suzhe.ymall.common.utils.YMConstant;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.method.HandlerMethod;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Set;

/**
 * @author suzhe
 * @date 2019/7/1
 */
@Slf4j
public class ManageAuthorizationHander implements AuthorizationHander{

    @Autowired
    RedisTemplateUtils redisTemplateUtils;

    @Autowired
    IPermissionService permissionService;

    @Override
    public boolean handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws AuthorizationException {
        String accessToken = request.getHeader(YMConstant.ACCESS_TOKEN);
        String tokenKey = RedisKeys.getTokenKeyForSys(accessToken);
        LoginAuth loginAuth;
        if(handler instanceof HandlerMethod) {
            loginAuth = ((HandlerMethod) handler).getMethodAnnotation(LoginAuth.class);
        }else{
            return true;
        }
        if(loginAuth == null){//如果请求的链接不包含 登录授权的注解 放行
            return true;
        }
        LoginUserUtils.removeSysLoginUser();
        SysLoginUser loginUser = null;
        //如果条件满足 取出redis里的用户 和 当前线程绑定
        if (StringUtils.isNotBlank(accessToken)) {
            loginUser = (SysLoginUser) redisTemplateUtils.get(tokenKey);
            log.debug("ManageAuthorizationHander:{}",loginUser);
            LoginUserUtils.setSysLoginUser(loginUser);
        }

        if (null == loginUser) {
            throw new AuthorizationException(ApiCode.NEED_LOGIN.getCode(),"需要登陆");
        }

        String permission = loginAuth.value();
        if (StringUtils.isNotBlank(permission)){//如果存在权限标识 在需要验证权限
            //获取用户所有的Action权限
            Set<String> actionPerms = permissionService.getActionPerms(loginUser.getId());
            if (!actionPerms.contains(permission)){//如果不包含该权限
                throw new AuthorizationException(ApiCode.AUTH_FAILURE.getCode(),"无权访问");
            }
        }

        //重置token的过期时间
        redisTemplateUtils.expire(tokenKey,YMConstant.MANAGE_TOKEN_EXPIRE_TIME);

        return true;
    }
}
